home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / glib / part13 < prev    next >
Encoding:
Text File  |  1989-05-21  |  44.6 KB  |  2,172 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v06i115: glib part 15 of 15
  4. Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  5.  
  6. Posting-number: Volume 6, Issue 115
  7. Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  8. Archive-name: glib/part13
  9.  
  10. [Parts 13 and 14 are uuencoded .arc files.  Doesn't *ANYBODY* read the
  11. guidelines???  (A copy follows this message, to remind you.)  I'm going
  12. to figure out what they are and dump them elsewhere.  In the meantime,
  13. don't look for them here.  ++bsa]
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 15 (of 15)."
  22. # Contents:  glib.c
  23. # Wrapped by lee@uhccux on Sun May  7 00:40:21 1989
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'glib.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'glib.c'\"
  27. else
  28. echo shar: Extracting \"'glib.c'\" \(41661 characters\)
  29. sed "s/^X//" >'glib.c' <<'END_OF_FILE'
  30. X#ifndef lint
  31. Xstatic char rcsid[] = "$Id: glib.c,v 1.6 89/05/06 17:13:24 lee Exp $";
  32. X#endif
  33. X/*
  34. X * GLIB - a Generic LIBrarian and editor for synths
  35. X *
  36. X * Tim Thompson's original with modifications by Michael Kesti,
  37. X *    Greg Lee, Alan Bland, Scott Snyder, Mark Rinfret
  38. X * $Log:    glib.c,v $
  39. X * Revision 1.6  89/05/06  17:13:24  lee
  40. X * rel. to comp.sources.misc
  41. X * 
  42. X */
  43. X
  44. X#include "glib.h"
  45. X#include <ctype.h>
  46. X
  47. Xchar *Reason = "";
  48. X
  49. Xint Currrow = 0;    /* at top of screen, for messages */
  50. Xint Libbank = 0;    /* from 0 to LIBBANKS-1, is the current library bank*/
  51. Xint Nsynths = 0;
  52. X
  53. Xint Lastvalue = 0;
  54. X
  55. Xchar *Currdata;
  56. Xchar *Yankdata;        /* current 'yank' buffer (middle of screen) */
  57. X
  58. Xstruct peredinfo *PE;    /* array of per-editor miscellany */
  59. X
  60. Xchar Buff[BUFSIZ];
  61. Xint Redraw = 0;        /* if non-0, edit screen is completely redrawn. */
  62. X            /* parameter functions can make use of this. */
  63. Xint Changed = 0;
  64. Xint DataID = 0;        /* Data Id for file write and read operations */
  65. X
  66. X/* All the global values below are set as appropriate for the */
  67. X/* synthesizer currently being dealt with. */
  68. X
  69. Xint Nvoices = 0;
  70. Xint Voicesize =0;
  71. Xint Namesize = 0;
  72. Xint Libindex;        /* from 0 to Nvoices-1 */
  73. Xint Synindex;        /* from 0 to Nvoices-1 */
  74. Xint Channel;
  75. Xint Editrow;        /* from 0 to NUMONSCREEN-1 */
  76. Xint Editcol;        /* 0==synth, 1==library */
  77. Xchar *Libdata;        /* current library data (includes all LIBBANKS) */
  78. X            /* ie. the stuff on the right side of the screen */
  79. Xchar *Syndata;        /* current synth data (1 bank), ie. the left side */
  80. Xstruct paraminfo *P;    /* list of parameter info */
  81. Xstruct labelinfo *L;    /* arbitrary screen labels for edit screen */
  82. Xchar *Synthname;
  83. X#ifdef SSS
  84. Xint *scr_p;
  85. Xint NParams;
  86. X#endif
  87. X#ifdef KAWAIK1
  88. Xchar sngnames[64][11];
  89. X#endif
  90. X
  91. Xint synthinfileflag = 0;
  92. Xint synthoutfileflag = 0;
  93. Xchar Syinfname[100], Syofname[100];
  94. X
  95. Xint (*Sendedit)();    /* function to send parameters to synth's edit buffer*/
  96. Xint (*Datain)();    /* convert data from file-storage format to the */
  97. X            /* format stored in the P[] parameter array (p_val) */
  98. Xint (*Dataout)();    /* reverse of Datain */
  99. Xint (*Sendone)();    /* function to send one (permanent) voice to synth */
  100. Xint (*Sendbulk)();    /* function to send bulk dump to synth */
  101. Xint (*Getbulk)();    /* reverse of Sendbulk */
  102. Xchar *(*Nameof)();    /* pulls voice name out of file-storage data */
  103. Xint (*Setnameof)();    /* reverse of Nameof */
  104. Xchar *(*Numof)();    /* convert voice number to on-screen text */
  105. Xint (*Cvtnum)();    /* convert visible voice number to std. format */
  106. Xint (*Cvtanum)();    /* convert alphanumeric voice number to std. format */
  107. X            /* should never define both Cvtnum and Cvtanum */
  108. X
  109. X#ifdef SSS
  110. X# define PARAMAT(r, c) (*(scr_p + Cols*(r) + (c)))
  111. X#endif
  112. X
  113. Xmain()
  114. X{
  115. X    int n;
  116. X
  117. X    hello();
  118. X    windinit();
  119. X    initstuff();
  120. X
  121. X    if ( Nsynths == 0 )
  122. X        windstr("Hey, the E array is empty?");
  123. X    else if ( Nsynths == 1 ) {
  124. X        /* If there's only 1 synth, don't bother asking */
  125. X        setedit(0);
  126. X        libinteract();
  127. X    }
  128. X    else {
  129. X        while ( (n=choosesynth()) >= 0 ) {
  130. X            setedit(n);
  131. X            libinteract();
  132. X            unsetedit(n);
  133. X        }
  134. X    }
  135. X    bye();
  136. X}
  137. X
  138. X/* choose a synth, returning its position in the E array */
  139. Xchoosesynth()
  140. X{
  141. X    int n, pick;
  142. X
  143. X    retry:
  144. X    flushconsole();
  145. X    windclear();
  146. X    windgoto(2,23);
  147. X#ifdef KAWAIK1
  148. X    windstr("Kawai K1 Librarian/Editor");
  149. X#else
  150. X#ifdef ROLANDD10
  151. X    windstr("Roland D-10 Librarian/Editor");
  152. X#else
  153. X    windstr("GLIB - A Generic Librarian/Editor");
  154. X#endif
  155. X#endif
  156. X
  157. X    for ( n=1; n<=Nsynths; n++ )
  158. X        libchoice(n);
  159. X    windgoto(8+Nsynths,27);
  160. X    windstr("q  -  Quit");
  161. X    windgoto(11+Nsynths,27);
  162. X    windstr("Make selection --> ");
  163. X    windrefresh();
  164. X    pick = mouseorkey();
  165. X    if ( pick == 'q' || pick == EOF )
  166. X        return(-1);
  167. X    if ( pick != MOUSE )
  168. X        pick = pick - '0';
  169. X    else {
  170. X        int row, col;
  171. X        getmouse(&row,&col);
  172. X        /* wait until mouse goes down */
  173. X        while ( statmouse() > 0 )
  174. X            ;
  175. X        pick = row - 6; 
  176. X    }
  177. X    if ( pick < 1 || pick > Nsynths )
  178. X        goto retry;
  179. X    return(pick-1);
  180. X}
  181. X
  182. Xlibchoice(n)
  183. X{
  184. X    windgoto(6+n,27);
  185. X    (void)sprintf(Buff,"%d  -  %s",n,E[n-1].ed_name);
  186. X    windstr(Buff);
  187. X}
  188. X
  189. X#ifndef SINGLEDATA
  190. X
  191. Xinitstuff()
  192. X{
  193. X    int n, banksize, maxvsize;
  194. X    
  195. X    maxvsize = 0;
  196. X    for ( n=0; E[n].ed_name != NULL; n++ ) {
  197. X        if ( maxvsize < E[n].ed_vsize )
  198. X            maxvsize = E[n].ed_vsize;
  199. X    }
  200. X    Nsynths = n;
  201. X    Currdata = alloc( maxvsize );
  202. X
  203. X    /* allocate an array of peredinfo structs */
  204. X    PE =(struct peredinfo *)alloc((int)(Nsynths*sizeof(struct peredinfo)));
  205. X    for ( n=0; n<Nsynths; n++ ) {
  206. X        banksize =  E[n].ed_nvoices * E[n].ed_vsize;
  207. X
  208. X        PE[n].ed_libdata = alloc(LIBBANKS * banksize);
  209. X        clrdata(PE[n].ed_libdata, LIBBANKS * banksize);
  210. X
  211. X        PE[n].ed_syndata = alloc(banksize);
  212. X        clrdata(PE[n].ed_syndata, banksize);
  213. X
  214. X        PE[n].ed_yankdata = alloc(E[n].ed_vsize);
  215. X        clrdata(PE[n].ed_yankdata, E[n].ed_vsize);
  216. X
  217. X        PE[n].ed_libindex = 0;
  218. X        PE[n].ed_synindex = 0;
  219. X        PE[n].ed_channel = 1;
  220. X        PE[n].ed_erow = 0;
  221. X        PE[n].ed_ecol = 0;
  222. X    }
  223. X}
  224. X
  225. X#else
  226. X
  227. Xinitstuff()
  228. X{
  229. X    int n, banksize, maxvsize;
  230. X    char *lib, *syn, *yank;
  231. X    
  232. X    maxvsize = 0;
  233. X    for ( n=0; E[n].ed_name != NULL; n++ ) {
  234. X        if ( maxvsize < E[n].ed_vsize )
  235. X            maxvsize = E[n].ed_vsize;
  236. X    }
  237. X    Nsynths = n;
  238. X    Currdata = alloc( maxvsize );
  239. X
  240. X    PE =(struct peredinfo *)alloc((int)(Nsynths*sizeof(struct peredinfo)));
  241. X
  242. X    /* allocate common data areas */
  243. X    banksize =  E[0].ed_nvoices * E[0].ed_vsize;
  244. X
  245. X    lib = alloc(LIBBANKS * banksize);
  246. X    clrdata(lib, LIBBANKS * banksize);
  247. X
  248. X    syn = alloc(banksize);
  249. X    clrdata(syn, banksize);
  250. X
  251. X    yank = alloc(E[0].ed_vsize);
  252. X    clrdata(yank, E[0].ed_vsize);
  253. X
  254. X    for ( n=0; n<Nsynths; n++ ) {
  255. X        PE[n].ed_libdata = lib;
  256. X        PE[n].ed_syndata = syn;
  257. X        PE[n].ed_yankdata = yank;
  258. X        PE[n].ed_libindex = 0;
  259. X        PE[n].ed_synindex = 0;
  260. X        PE[n].ed_channel = 1;
  261. X        PE[n].ed_erow = 0;
  262. X        PE[n].ed_ecol = 0;
  263. X    }
  264. X}
  265. X
  266. X#endif
  267. X
  268. Xclrdata(data,size)
  269. Xchar *data;
  270. X{
  271. X    register char *p, *endp;
  272. X
  273. X    p = data;
  274. X    endp = data+size;
  275. X
  276. X    while ( p<endp )
  277. X        *p++ = 0;
  278. X}
  279. X
  280. X#ifdef SSS
  281. Xint paramcmp(p1, p2)
  282. Xstruct paraminfo *p1, *p2;
  283. X{
  284. X  return strcmp(p1->p_name, p2->p_name);
  285. X}
  286. X
  287. Xinit_params()
  288. X{
  289. X  int i;
  290. X
  291. X  for (NParams=0; P[NParams].p_name != NULL; NParams++)
  292. X    ;
  293. X  qsort((void *)P, NParams, sizeof(struct paraminfo), paramcmp);
  294. X
  295. X  scr_p = (int *)alloc(Rows * Cols * sizeof(int));
  296. X  clrdata((char *)scr_p, Rows * Cols * sizeof(int));
  297. X  for (i=0; i<NParams; i++) {
  298. X    int r = P[i].p_vrow;
  299. X    int c = P[i].p_vcol;
  300. X
  301. X    if (r >= 0 && r < Rows && c >= 0 && c < Cols)
  302. X      PARAMAT(r, c) = i+1;
  303. X  }
  304. X}
  305. X#endif
  306. X
  307. X#ifndef SINGLEDATA
  308. X
  309. Xsetedit(n)
  310. X{
  311. X    Synthname = E[n].ed_name;
  312. X    Datain = E[n].ed_din;
  313. X    Dataout = E[n].ed_dout;
  314. X    Nvoices = E[n].ed_nvoices;
  315. X    Sendedit = E[n].ed_sedit;
  316. X    Sendone = E[n].ed_sone;
  317. X    Sendbulk = E[n].ed_sbulk;
  318. X    Getbulk = E[n].ed_gbulk;
  319. X    Nameof = E[n].ed_nof;
  320. X    Numof = E[n].ed_numof;
  321. X    Cvtnum = E[n].ed_cvtnum;
  322. X    Cvtanum = E[n].ed_cvtanum;
  323. X    Setnameof = E[n].ed_snof;
  324. X    Voicesize = E[n].ed_vsize;
  325. X    Namesize = E[n].ed_nsize;
  326. X    DataID = E[n].ed_dataid;
  327. X    Libdata = PE[n].ed_libdata;
  328. X    Syndata = PE[n].ed_syndata;
  329. X    Yankdata = PE[n].ed_yankdata;
  330. X    Libindex = PE[n].ed_libindex;
  331. X    Synindex = PE[n].ed_synindex;
  332. X    Channel = PE[n].ed_channel;
  333. X    Editrow = PE[n].ed_erow;
  334. X    Editcol = PE[n].ed_ecol;
  335. X    clrdata(Currdata,Voicesize);
  336. X    P = E[n].ed_params;
  337. X    L = E[n].ed_labels;
  338. X
  339. X#ifdef SSS
  340. X        init_params();
  341. X#endif
  342. X}
  343. X
  344. Xunsetedit(n)
  345. X{
  346. X    int k;
  347. X
  348. X    DataID = 0;
  349. X    PE[n].ed_libindex = Libindex;
  350. X    PE[n].ed_synindex = Synindex;
  351. X    PE[n].ed_channel = Channel;
  352. X    PE[n].ed_erow = Editrow;
  353. X    PE[n].ed_ecol = Editcol;
  354. X    for ( k=0; k<Voicesize; k++ )
  355. X        PE[n].ed_yankdata[k] = Yankdata[k];
  356. X}
  357. X
  358. X#else
  359. X
  360. Xsetedit(n)
  361. X{
  362. X    Synthname = E[n].ed_name;
  363. X    Datain = E[n].ed_din;
  364. X    Dataout = E[n].ed_dout;
  365. X    Nvoices = E[n].ed_nvoices;
  366. X    Sendedit = E[n].ed_sedit;
  367. X    Sendone = E[n].ed_sone;
  368. X    Sendbulk = E[n].ed_sbulk;
  369. X    Getbulk = E[n].ed_gbulk;
  370. X    Nameof = E[n].ed_nof;
  371. X    Numof = E[n].ed_numof;
  372. X    Cvtnum = E[n].ed_cvtnum;
  373. X    Cvtanum = E[n].ed_cvtanum;
  374. X    Setnameof = E[n].ed_snof;
  375. X    Voicesize = E[n].ed_vsize;
  376. X    Namesize = E[n].ed_nsize;
  377. X    DataID = E[n].ed_dataid;
  378. X    Libdata = PE[n].ed_libdata;
  379. X    Syndata = PE[n].ed_syndata;
  380. X    Yankdata = PE[n].ed_yankdata;
  381. X    Libindex = PE[n].ed_libindex;
  382. X    Synindex = PE[n].ed_synindex;
  383. X    Channel = PE[n].ed_channel;
  384. X    Editrow = PE[n].ed_erow;
  385. X    Editcol = PE[n].ed_ecol;
  386. X    clrdata(Currdata,Voicesize);
  387. X    P = E[n].ed_params;
  388. X    L = E[n].ed_labels;
  389. X#ifdef SSS
  390. X        init_params();
  391. X#endif
  392. X}
  393. X
  394. Xunsetedit(n)
  395. X{
  396. X    int j, k;
  397. X
  398. X    DataID = 0;
  399. X    for(j=0; j < Nsynths; j++) {
  400. X        PE[j].ed_libindex = Libindex;
  401. X        PE[j].ed_synindex = Synindex;
  402. X        PE[j].ed_channel = Channel;
  403. X        PE[j].ed_erow = Editrow;
  404. X        PE[j].ed_ecol = Editcol;
  405. X        for ( k=0; k<Voicesize; k++ ) {
  406. X            PE[j].ed_yankdata[k] = Yankdata[k];
  407. X        }
  408. X    }
  409. X}
  410. X
  411. X#endif
  412. X
  413. X/* template - show the boxes and such on the main library screen */
  414. Xtemplate()
  415. X{
  416. X    int n, k, r;
  417. X
  418. X    r = FIRSTROW-1;
  419. X    (void)sprintf(Buff,"%s",Synthname);
  420. X    n = 13 - strlen(Buff)/2;    /* center it */
  421. X    windgoto(r,n<0?0:n);
  422. X    windstr(Buff);
  423. X    r++;
  424. X    windgoto(r,0);
  425. X    for ( n=0; n<25; n++ )
  426. X        windputc('=');
  427. X    windgoto(r,53);
  428. X    for ( n=0; n<25; n++ )
  429. X        windputc('=');
  430. X    for ( n=r+1; n<(r+13); n++ ) {
  431. X        windgoto(n,0);
  432. X        windputc('|');
  433. X        windgoto(n,5);
  434. X        windputc('|');
  435. X        windgoto(n,24);
  436. X        windputc('|');
  437. X
  438. X        k=53;
  439. X        windgoto(n,k);
  440. X        windputc('|');
  441. X        windgoto(n,k+5);
  442. X        windputc('|');
  443. X        windgoto(n,k+24);
  444. X        windputc('|');
  445. X    }
  446. X    windgoto(r+13,0);
  447. X    for ( n=0; n<25; n++ )
  448. X        windputc('=');
  449. X    windgoto(r+13,53);
  450. X    for ( n=0; n<25; n++ )
  451. X        windputc('=');
  452. X
  453. X    windgoto(YANKROW-2,YANKCOL);
  454. X    windstr("  Yank Buffer");
  455. X    windgoto(YANKROW-1,YANKCOL);
  456. X    windstr(" ------------- ");
  457. X    windgoto(YANKROW,YANKCOL);
  458. X    windstr("               ");
  459. X    windgoto(YANKROW+1,YANKCOL);
  460. X    windstr(" ------------- ");
  461. X    windrefresh();
  462. X}
  463. X
  464. X/* clear the message area */
  465. Xclearmess()
  466. X{
  467. X    int n;
  468. X    for(n=1;n<(FIRSTROW-1);n++)
  469. X        winderaserow(n);
  470. X    Currrow = 0;
  471. X}
  472. X
  473. X/* set the current voice (ie. the synth's edit buffer) to the indicated */
  474. X/* voice.  c==0 is the synth (left) side, c==1 is the library (right) side. */
  475. Xeditto(r,c)
  476. X{
  477. X    int voicenum;
  478. X
  479. X    /* Clear the existing '*' */
  480. X    editchar(' ',Editrow,Editcol);
  481. X    editchar('*',Editrow=r,Editcol=c);
  482. X    if ( Editcol==0 ) {
  483. X        /* we're on the synth side */
  484. X        voicenum = Editrow+Synindex;
  485. X        tocurrent(Syndata,voicenum);
  486. X    }
  487. X    else {
  488. X        /* we're on the lib side */
  489. X        voicenum = Editrow+Libindex;
  490. X        tocurrent(bankvoice(0),voicenum);
  491. X    }
  492. X}
  493. X
  494. Xeditchar(ec,r,c)
  495. X{
  496. X    r = r + FIRSTROW + 1;
  497. X    if ( c == 0 )
  498. X        c = LEFTSIDE-1;
  499. X    else
  500. X        c = RIGHTSIDE-1;
  501. X    windgoto(r,c);
  502. X    windputc(ec);
  503. X    windrefresh();
  504. X}
  505. X
  506. X/* control interaction on the main library bank screen */
  507. Xlibinteract()
  508. X{
  509. X    int c, n, swap, voicenum, maxindex, q;
  510. X    char *p, *data;
  511. X
  512. X    flushmidi();
  513. X    drawall();
  514. X    for ( ;; ) {
  515. X        Currrow = 0;
  516. X        winderaserow(Currrow);
  517. X        windgoto(Currrow,0);
  518. X        windstr("Command --> ");
  519. X        windrefresh();
  520. X        
  521. X        c = mouseorkey();
  522. X        if ( c == MOUSE ) {
  523. X            libmouse();
  524. X            continue;
  525. X        }
  526. X
  527. X        if ( isprint(c) )
  528. X            windputc(c);
  529. X        clearmess();
  530. X        switch ( c ) {
  531. X        case ' ':
  532. X            playnote(1);
  533. X            break;
  534. X        case '\n':
  535. X#ifndef macintosh
  536. X        case '\r':
  537. X#endif
  538. X            /* ignore */
  539. X            break;
  540. X        case EOF:
  541. X        case 'q':
  542. X            return;
  543. X        case CH_REDRAW:
  544. X            drawall();
  545. X            break;
  546. X        case 's':
  547. X        case 'p':
  548. X            swap = (c=='s')?1:0;
  549. X            if ( Editcol==0 )
  550. X                tosyn(Synindex+Editrow,Yankdata,swap);
  551. X            else
  552. X                tolib(Libindex+Editrow,Yankdata,swap);
  553. X            updatedisplay();
  554. X            pryankname();
  555. X            break;
  556. X        case 'y':
  557. X            for(n=0;n<Voicesize;n++)
  558. X                Yankdata[n] = Currdata[n];
  559. X            pryankname();
  560. X            break;
  561. X        case '?':
  562. X            helpmessage();
  563. X            break;
  564. X        case SCR_DOWN:
  565. X            if(Nvoices < NUMONSCREEN)
  566. X                q = Nvoices;
  567. X            else
  568. X                q = NUMONSCREEN;
  569. X
  570. X            maxindex = Nvoices - q;
  571. X            if ( Editcol==0 ) {
  572. X                /* we're on the synth side */
  573. X                if ( (Synindex+=q/2) > maxindex )
  574. X                    Synindex = maxindex;
  575. X            }
  576. X            else {
  577. X                /* we're on the lib side */
  578. X                if ( (Libindex+=q/2) > maxindex )
  579. X                    Libindex = maxindex;
  580. X            }
  581. X            updatedisplay();
  582. X            break;
  583. X        case SCR_UP:
  584. X            if ( Editcol==0 ) {
  585. X                /* we're on the synth side */
  586. X                if ( (Synindex-=NUMONSCREEN/2) < 0 )
  587. X                    Synindex = 0;
  588. X            }
  589. X            else {
  590. X                /* we're on the lib side */
  591. X                if ( (Libindex-=NUMONSCREEN/2) < 0 )
  592. X                    Libindex = 0;
  593. X            }
  594. X            updatedisplay();
  595. X            break;
  596. X        case '\033':
  597. X        case '`':
  598. X            allnotesoff();
  599. X            break;
  600. X        case 't':
  601. X            transcmd();
  602. X            editto(Editrow,Editcol);
  603. X            break;
  604. X        case 'D':    /* download FROM file */
  605. X            synthinfileflag = 1;
  606. X        case 'd':    /* download FROM synth */
  607. X            clrdata(Syndata,Nvoices*Voicesize);
  608. X            if ( readsynth(Syndata) == 0 ) {
  609. X                syntodisplay(Synindex=0);
  610. X                if(Editcol == 0)
  611. X                    editto(Editrow,Editcol);
  612. X            }
  613. X            synthinfileflag = 0;
  614. X            break;
  615. X        case 'U':    /* upload to file */
  616. X            synthoutfileflag = 1;
  617. X        case 'u':    /* upload TO synth */
  618. X            if ( Editcol==0 ) {
  619. X                voicenum = Editrow+Synindex;
  620. X                data = &(VOICEBYTE(Syndata,voicenum,0));
  621. X            }
  622. X            else
  623. X                data = bankvoice(Editrow+Libindex);
  624. X            upload(data);
  625. X            synthoutfileflag = 0;
  626. X            break;
  627. X        case 'r':
  628. X            readall();
  629. X            if(Editcol == 1)
  630. X                editto(Editrow,Editcol);
  631. X            break;
  632. X        case 'R':
  633. X            readprintable();
  634. X            if(Editcol == 1)
  635. X                editto(Editrow,Editcol);
  636. X            break;
  637. X        case 'w':
  638. X            writeall();
  639. X            break;
  640. X        case 'W':
  641. X            writeprintable();
  642. X            break;
  643. X        case 'c':
  644. X            setchan();
  645. X            break;
  646. X        case 'b':
  647. X            /* cycle through banks, from 0 to LIBBANKS-1 */
  648. X            if ( ++Libbank >= LIBBANKS )
  649. X                Libbank = 0;
  650. X            libtodisplay(Libindex);
  651. X            updatedisplay();
  652. X            break;
  653. X        case 'e':
  654. X            if ( Namesize == 0)
  655. X                p = NULL;
  656. X            else
  657. X                p = (*Nameof)(Currdata);
  658. X            if ( Editcol==0 ) {
  659. X                voicenum = Editrow+Synindex;
  660. X                data = &(VOICEBYTE(Syndata,voicenum,0));
  661. X                editdata(p,data);
  662. X                windclear();
  663. X                /* Update Currdata */
  664. X                for ( n=0; n<Voicesize; n++ )
  665. X                    Currdata[n] = VOICEBYTE(Syndata,voicenum,n);
  666. X            }
  667. X            else {
  668. X                data = bankvoice(Editrow+Libindex);
  669. X                editdata(p,data);
  670. X            }
  671. X            drawall();
  672. X            break;
  673. X        case 'g': /* goto a specific voice */
  674. X            do_goto();
  675. X            break;
  676. X        case CH_LEFT:
  677. X        case ALTCH_LEFT:
  678. X            if ( Editcol==1 )
  679. X                editto(Editrow,0);
  680. X            break;
  681. X        case CH_DOWN:
  682. X        case ALTCH_DOWN:
  683. X            if(Nvoices < NUMONSCREEN)
  684. X                q = Nvoices;
  685. X            else
  686. X                q = NUMONSCREEN;
  687. X            if ( Editrow < (q-1) )
  688. X                editto(Editrow+1,Editcol);
  689. X            else {
  690. X                /* we're at the bottom, so try to scroll */
  691. X                if ( Editcol==0 ) {
  692. X                    /* we're on the synth side */
  693. X                    if (Synindex<(Nvoices-q))
  694. X                        Synindex++;
  695. X                }
  696. X                else {
  697. X                    /* we're on the lib side */
  698. X                    if (Libindex<(Nvoices-q))
  699. X                        Libindex++;
  700. X                }
  701. X                updatedisplay();
  702. X            }
  703. X            break;
  704. X        case CH_UP:
  705. X        case ALTCH_UP:
  706. X            if ( Editrow>0 )
  707. X                editto(Editrow-1,Editcol);
  708. X            else {
  709. X                /* we're at the top, so try to scroll */
  710. X                if ( Editcol==0 ) {
  711. X                    /* we're on the synth side */
  712. X                    if (Synindex>0)
  713. X                        Synindex--;
  714. X                }
  715. X                else {
  716. X                    /* we're on the lib side */
  717. X                    if (Libindex>0)
  718. X                        Libindex--;
  719. X                }
  720. X                updatedisplay();
  721. X            }    
  722. X            break;
  723. X        case CH_RIGHT:
  724. X        case ALTCH_RIGHT:
  725. X            if ( Editcol==0 )
  726. X                editto(Editrow,1);
  727. X            break;
  728. X        case 'f':
  729. X            filelist();
  730. X            break;
  731. X        default:
  732. X            message("Unrecognized command!  Press '?' for help.");
  733. X            break;
  734. X        }
  735. X    }
  736. X}
  737. X
  738. Xfilelist()
  739. X{
  740. X    char *p, *q, buff[BUFSIZ];
  741. X    int n, ninline = 0, nprinted = 0;
  742. X
  743. X    clearmess();
  744. X    Currrow = -1;    /* To start message on top line */
  745. X    openls();
  746. X    message("Files in current directory:");
  747. X    strcpy(buff,"  ");
  748. X    while ( (p=nextls()) != NULL ) {
  749. X        /* add the next file to the line being constructed */
  750. X        q = &buff[strlen(buff)];
  751. X        strcpy(q,p);
  752. X        q += (n=strlen(p));
  753. X        while ( n++ < 15 )
  754. X            *q++ = ' ';
  755. X        *q = '\0';
  756. X        if ( ninline++ > 3 ) {
  757. X            message(buff);
  758. X            if ( nprinted++ > 4 ) {
  759. X                message("Press any key to continue ...");
  760. X                (void)getconsole();
  761. X                clearmess();
  762. X                nprinted = 0;
  763. X            }
  764. X            strcpy(buff,"  ");
  765. X            ninline = 0;
  766. X        }
  767. X    }
  768. X    if ( ninline > 0 )
  769. X        message(buff);
  770. X    closels();
  771. X}
  772. X
  773. Xlibmouse()
  774. X{
  775. X    int row, col, q;
  776. X
  777. X    getmouse(&row,&col);
  778. X    if(Nvoices < NUMONSCREEN)
  779. X        q = Nvoices;
  780. X    else
  781. X        q = NUMONSCREEN;
  782. X    if ( row <= FIRSTROW || row > FIRSTROW+q+1 )
  783. X        goto getout;
  784. X    if ( col < Cols/2 )
  785. X        col = 0;
  786. X    else
  787. X        col = 1;
  788. X    row = row - FIRSTROW - 1;
  789. X    editto(row,col);
  790. Xgetout:
  791. X    /* wait until mouse button is released */
  792. X    while ( statmouse() > 0 )
  793. X        ;
  794. X}
  795. X
  796. Xdo_goto()
  797. X{
  798. X    int n, r, maxindex, new_ecol,q;
  799. X    char sbuf[100], *sp;
  800. X    
  801. X    message("");
  802. X    message("Where to? ");
  803. X    windgets(sbuf);
  804. X    
  805. X    sp = sbuf;
  806. X    switch(*sp++) {
  807. X      case 's': /* synth side */
  808. X        new_ecol = 0;
  809. X        break;
  810. X      case 'l': /* library side */
  811. X        new_ecol = 1;
  812. X        break;
  813. X      default: /* no change in side */
  814. X          new_ecol = Editcol;
  815. X        sp--;    /* but don't trash the first character */
  816. X        break;
  817. X    }
  818. X    
  819. X    clearmess();
  820. X    r = sscanf(sp, "%d", &n); /* this may fail - we handle it later */
  821. X    if(Cvtnum != NULL) { /* convert to internal format if needed */
  822. X        n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */
  823. X    }
  824. X    if (Cvtanum != NULL) { /* convert using alphanumeric voice number */
  825. X        n = (*Cvtanum)(sp) + 1;
  826. X        if (n) r = 1;
  827. X    }
  828. X    if(r != 1) {
  829. X        message("type one of: sn, ln, or n");
  830. X        message("  s = synth side (literal character 's')");
  831. X        message("  l = library side (literal character 'l')");
  832. X#ifdef KAWAIK1
  833. X        message("  n = voice number to select (letter + number)");
  834. X#else
  835. X#ifdef KAWAIK5
  836. X        message("  n = voice number to select (letter + number)");
  837. X#else
  838. X        message("  n = voice number to select (an integer)");
  839. X#endif
  840. X#endif
  841. X        return;
  842. X    }
  843. X    if(n <= 0 || n > Nvoices) { /* 1-based */
  844. X        message("Bad voice number!");
  845. X        return;
  846. X    }
  847. X    
  848. X    /* it can be done.  nuke the old '*' and change columes (if needed) */
  849. X    editchar(' ', Editrow, Editcol);
  850. X    Editcol = new_ecol;
  851. X    
  852. X    /* try to center it */
  853. X    if(Nvoices < NUMONSCREEN)
  854. X        q = Nvoices;
  855. X    else
  856. X        q = NUMONSCREEN;
  857. X    maxindex = Nvoices - q;
  858. X    if(Editcol == 0) {
  859. X        Synindex = (n - 1) - q/2; /* 0-based */
  860. X        if(Synindex < 0) { /* impossible to center */
  861. X            Synindex = 0; /* so do your best */
  862. X        } else if(Synindex > maxindex) {
  863. X            Synindex = maxindex;
  864. X        }
  865. X        Editrow = (n - 1) - Synindex; /* and put a '*' on it */
  866. X    } else {
  867. X        Libindex = (n - 1) - q/2; /* 0-based */
  868. X        if(Libindex < 0) {
  869. X            Libindex = 0;
  870. X        } else if(Libindex > maxindex) {
  871. X            Libindex = maxindex;
  872. X        }
  873. X        Editrow = (n - 1) - Libindex;
  874. X    }
  875. X    
  876. X    updatedisplay(); /* do the real work */
  877. X    return;
  878. X}
  879. X
  880. Xupload(data)
  881. Xchar *data;
  882. X{
  883. X    int c, n;
  884. X    char num[16];
  885. X
  886. X    message("");
  887. X    if (synthoutfileflag) {
  888. X        message("Upload to synth file:");
  889. X        message("Output synth file --> ");
  890. X        windgets(Syofname);
  891. X        flushmidi();
  892. X    }
  893. X    else message("Upload TO synth:");
  894. X    message("                 c - current voice");
  895. X    message("                 a - ALL voices");
  896. X    message("Choose --> ");
  897. X    c = getconsole();
  898. X    if ( c == 'c' ) {
  899. X        clearmess();
  900. X        if ( Sendone == NULL ) {
  901. X            if (synthoutfileflag) (*Sendedit)(data);
  902. X            else
  903. X            message("Single voices can't be sent to that synth!");
  904. X            return;
  905. X        }
  906. X        message("What voice number to you want to send it TO? --> ");
  907. X        windgets(num);
  908. X        clearmess();
  909. X        n = atoi(num);
  910. X        if(Cvtnum != NULL) { /* convert to internal format if needed */
  911. X            n = (*Cvtnum)(n) + 1; /* we are 1-based for user input */
  912. X        }
  913. X        if (Cvtanum != NULL) { /* howzabout alphanumeric format? */
  914. X            n = (*Cvtanum)(num) + 1;
  915. X        }
  916. X        if ( n > 0 && n <= Nvoices ) {
  917. X            if ( (*Sendone)(n-1,data) != 0 ) { /* 0-based on calls -SAF */
  918. X                message("Unable to write data to synth!");
  919. X                (void)sprintf(Buff,"Reason: %s",Reason);
  920. X                message(Buff);
  921. X                return;
  922. X            }
  923. X        } else {
  924. X            message("Bad voice number!");
  925. X        }
  926. X    }
  927. X    else if ( c == 'a' ) {
  928. X        clearmess();
  929. X        if ( Sendbulk != NULL ) {
  930. X            message("Uploading to synth using bulk routine.");
  931. X            if ( (*Sendbulk)(Syndata) != 0 ) {
  932. X                message("Upload failure!");
  933. X                (void)sprintf(Buff,"Reason: %s\n",Reason);
  934. X                message(Buff);
  935. X                return;
  936. X            }
  937. X        } else {
  938. X            message("Uploading to synth using single routine.");
  939. X            for ( n=0; n<Nvoices; n++ ) {
  940. X                if ( (*Sendone)(n, &(VOICEBYTE(Syndata,n,0)) ) != 0 ) {
  941. X                    message("Unable to write data to synth!");
  942. X                    (void)sprintf(Buff,"Reason: %s",Reason);
  943. X                    message(Buff);
  944. X                    return;
  945. X                }
  946. X            }
  947. X        }
  948. X        /* clearmess(); */
  949. X    }
  950. X    else {
  951. X        clearmess();
  952. X        message("Bad choice!");
  953. X    }
  954. X}
  955. X
  956. Xhelpmessage()
  957. X{
  958. Xclearmess();
  959. X(void)sprintf(Buff,"%s,%s,%s,%s - move around              e - edit current voice",
  960. X    STR_LEFT,STR_DOWN,STR_UP,STR_RIGHT);
  961. Xmessage(Buff);
  962. Xmessage("r - read voices from a file        y - yank into buffer");
  963. Xmessage("w - write voices to a file         p - put from buffer");
  964. Xmessage("b - cycle through library banks    s - swap current voice with yank buffer");
  965. Xmessage("t - transfer all voices            f - list files in current directory");
  966. Xmessage("d - download voices from synth     c - set MIDI channel");
  967. Xmessage("u - upload voices to synth         g - 'goto' form of moving around");
  968. Xmessage("q - quit                           <space> - play a note");
  969. X}
  970. X
  971. Xupdatedisplay()
  972. X{
  973. X    if ( Editcol==0 ) {
  974. X        /* we're on the synth side */
  975. X        syntodisplay(Synindex);
  976. X        editto(Editrow,Editcol);
  977. X    }
  978. X    else {
  979. X        /* we're on the lib side */
  980. X        libtodisplay(Libindex);
  981. X        editto(Editrow,Editcol);
  982. X    }
  983. X}
  984. X
  985. Xpryankname()
  986. X{
  987. X    char ybuff[33];
  988. X    char *p;
  989. X
  990. X    if ( Namesize == 0 )
  991. X        return;
  992. X
  993. X    windgoto(YANKROW,YANKCOL-4);
  994. X    windstr("                    ");
  995. X    strcpy(ybuff,(*Nameof)(Yankdata));
  996. X    /* take off trailing blanks */
  997. X    p = ybuff + strlen(ybuff) - 1;
  998. X    while ( p>ybuff && *p == ' ' )
  999. X        *p-- = '\0';
  1000. X    windgoto(YANKROW,YANKCOL+7-strlen(ybuff)/2);
  1001. X    windstr(ybuff);
  1002. X    windrefresh();
  1003. X}
  1004. X
  1005. Xtranscmd()
  1006. X{
  1007. X    int fromc;
  1008. X
  1009. X    message("");
  1010. X    message("Transfer ALL voices:");
  1011. X    message("                       1:   <<-----   from library bank to synth bank");
  1012. X    message("                       2:   ----->>   from synth bank to library bank");
  1013. X    message("1 or 2 --> ");
  1014. X    fromc = getconsole();
  1015. X    windputc(fromc);
  1016. X    if ( fromc!='1' && fromc!='2' ) {
  1017. X        clearmess();
  1018. X        return;
  1019. X    }
  1020. X    switch ( fromc ) {
  1021. X    case '1':
  1022. X        copyall(bankvoice(0),Syndata);
  1023. X        syntodisplay(Synindex);
  1024. X        clearmess();
  1025. X        message("Use the 'u'pload command to actually send the synth bank voices to the synth.");
  1026. X        break;
  1027. X    case '2':
  1028. X        copyall(Syndata,bankvoice(0));
  1029. X        libtodisplay(Libindex);
  1030. X        clearmess();
  1031. X        break;
  1032. X    }
  1033. X}
  1034. X
  1035. Xcopyall(fromdata,todata)
  1036. Xchar *fromdata;
  1037. Xchar *todata;
  1038. X{
  1039. X    int n, v;
  1040. X
  1041. X    for ( v=0; v<Nvoices; v++ )
  1042. X        for ( n=0; n<Voicesize; n++ )
  1043. X            VOICEBYTE(todata,v,n) = VOICEBYTE(fromdata,v,n);
  1044. X}
  1045. X
  1046. Xmessage(s)
  1047. Xchar *s;
  1048. X{
  1049. X    windgoto(++Currrow,0);
  1050. X    windstr(s);
  1051. X    windrefresh();
  1052. X}
  1053. X
  1054. Xsetchan()
  1055. X{
  1056. X    int c;
  1057. X
  1058. X    message("New MIDI channel --> ");
  1059. X    windgets(Buff);
  1060. X    if ( (c=atoi(Buff)) <= 0 || c > 16 ) {
  1061. X        clearmess();
  1062. X        message("Invalid channel!");
  1063. X    }
  1064. X    else {
  1065. X        clearmess();
  1066. X        Channel = c;
  1067. X        showchan();
  1068. X    }
  1069. X}
  1070. X
  1071. Xshowchan()
  1072. X{
  1073. X    windgoto(20,31);
  1074. X    windstr("MIDI Channel: ");
  1075. X    (void)sprintf(Buff,"%d ",Channel);
  1076. X    windstr(Buff);
  1077. X    windrefresh();
  1078. X}
  1079. X
  1080. X#ifdef DX7
  1081. X#include <sys/types.h>
  1082. X#include <sys/stat.h>
  1083. Xlong flength(handle)
  1084. Xint handle;
  1085. X{
  1086. X  struct stat buf;
  1087. X  fstat(handle, &buf);
  1088. X  return buf.st_size;
  1089. X}
  1090. X#endif
  1091. X
  1092. X/* read data from a file, filling the current library bank. */
  1093. Xreadall()
  1094. X{
  1095. X    char fname[100];
  1096. X    FILE *f;
  1097. X    int v, n, r;
  1098. X    char *p;
  1099. X
  1100. X    message("File name --> ");
  1101. X    windgets(fname);
  1102. X#ifdef BSD
  1103. X    OPENBINFILE(f,fname,"r");
  1104. X#else
  1105. X    OPENBINFILE(f,fname,"rb");
  1106. X#endif
  1107. X    if (f == NULL ) {
  1108. X        (void)sprintf(Buff,"Can't open '%s'!",fname);
  1109. X        message(Buff);
  1110. X        return;
  1111. X    }
  1112. X    /* If the first byte matches DataID, then the format is OK. */
  1113. X    if (DataID) n = (getc(f) & 0xff);
  1114. X    else n = 0;
  1115. X
  1116. X#ifndef ROLANDD10
  1117. X# ifndef KAWAIIK1
  1118. X/* If we are running the Aztec C compiler, it's not yet ANSII.  The
  1119. X   abominable kludge that follows is therefore necessary.           */
  1120. X#  ifdef AZTEC_C
  1121. X#    ifdef DX7
  1122. X#     define SKIP_IT
  1123. X#    endif
  1124. X#    ifdef DX7S
  1125. X#     define SKIP_IT
  1126. X#    endif
  1127. X#    ifndef SKIP_IT
  1128. X    if (n != DataID && n <= 31) {
  1129. X        (void)ungetc(n,f);
  1130. X        n = DataID;
  1131. X    }
  1132. X#    endif
  1133. X#    undef SKIP_IT
  1134. X#  else
  1135. X#   if !defined(DX7) && !defined(DX7S)
  1136. X        if (n != DataID && n <= 31) {
  1137. X                (void)ungetc(n,f);
  1138. X                n = DataID;
  1139. X        }
  1140. X#   endif
  1141. X#  endif
  1142. X# endif
  1143. X#endif
  1144. X
  1145. X#ifdef DX7S
  1146. X
  1147. X/* check for reading a DX7 file in DX7s mode */
  1148. X
  1149. X        if ( strcmp(Synthname, "DX7s") == 0 )
  1150. X          if (flength(fileno(f)) == 4096) {
  1151. X            (void)ungetc(n, f);
  1152. X            dx7Sread_dx7(f, bankvoice(0));
  1153. X            r = 0;
  1154. X            goto done;
  1155. X          }
  1156. X
  1157. X/* check for reading a DX7S file in DX7 mode */
  1158. X
  1159. X          if ( strcmp(Synthname, "DX7") == 0 ) {
  1160. X            n = getc(f) & 0xff;
  1161. X            if (n == 0xd7) {    /* DX7s dataID */
  1162. X              dx7read_dx7S(f, bankvoice(0));
  1163. X              r = 0;
  1164. X              goto done;
  1165. X            }
  1166. X            (void)ungetc(n, f);
  1167. X            n = 0;
  1168. X          }
  1169. X#endif
  1170. X
  1171. X#ifdef DX7
  1172. X
  1173. X/* validate a DX7 file based on length */
  1174. X
  1175. X        if ( strcmp(Synthname, "DX7") == 0 ) {
  1176. X          if (flength(fileno(f)) != Nvoices * Voicesize)
  1177. X            n = DataID + 1;
  1178. X        }
  1179. X
  1180. X#endif
  1181. X
  1182. X    if ( n == DataID ) {
  1183. X        p = bankvoice(0);
  1184. X        for ( v=0; v<Nvoices; v++ ) {
  1185. X            for ( n=0; n<Voicesize; n++ )
  1186. X#ifdef CZ1
  1187. X                *p++ = getc(f);
  1188. X#else
  1189. X#ifdef CZ101
  1190. X                *p++ = getc(f);
  1191. X#else
  1192. X                *p++ = (getc(f) & 0x7f);
  1193. X#endif
  1194. X#endif
  1195. X        }
  1196. X        r = 0;
  1197. X    } else {
  1198. X        (void)sprintf(Buff, "'%s' is invalid for this function!\n", fname);
  1199. X        message(Buff);
  1200. X        r = 1;
  1201. X    }
  1202. X#ifdef DX7S
  1203. Xdone:
  1204. X#endif
  1205. X    (void)fclose(f);
  1206. X    if ( r==0 ) {
  1207. X        libtodisplay(Libindex=0);
  1208. X        clearmess();
  1209. X    }
  1210. X}
  1211. X
  1212. X/* read printable data from a textfile, filling the current library bank. */
  1213. Xreadprintable()
  1214. X{
  1215. X    char fname[100];
  1216. X    FILE *pfin;
  1217. X    int v, n, r, val;
  1218. X    char *p = NULL;
  1219. X    char vname[20];
  1220. X
  1221. X    message("File name --> ");
  1222. X    windgets(fname);
  1223. X#ifdef BSD
  1224. X    OPENBINFILE(pfin,fname,"r");
  1225. X#else
  1226. X    OPENBINFILE(pfin,fname,"rb");
  1227. X#endif
  1228. X    if (pfin == NULL ) {
  1229. X        (void)sprintf(Buff,"Can't open '%s'!",fname);
  1230. X        message(Buff);
  1231. X        return;
  1232. X    }
  1233. X    /* If the first byte matches DataID, then the format is OK. */
  1234. X    r = fscanf(pfin, "BANK TYPE %d", &n);
  1235. X
  1236. X    v = -1;
  1237. X    if ( r == 1 && n == DataID ) while (r) {
  1238. X        r = fscanf(pfin, " %s ", vname);
  1239. X
  1240. X        if (r == 1) {
  1241. X        if (strcmp(vname, "voice") == 0) {
  1242. X            if (v > 0) (*Dataout)(p);
  1243. X            r = fscanf(pfin,"%d = %[ !-~]", &v, vname);
  1244. X            if (r == 2 && v > 0) {
  1245. X                p = bankvoice(v-1);
  1246. X                (*Setnameof)(p, vname);
  1247. X            }
  1248. X        } else {
  1249. X            r = fscanf(pfin, "= %d", &val);
  1250. X            if (r == 1) setval(vname, val);
  1251. X        }
  1252. X        }
  1253. X        if (r == EOF) r = 0;
  1254. X    } else {
  1255. X        (void)sprintf(Buff, "'%s' is invalid for this function!\n", fname);
  1256. X        message(Buff);
  1257. X        r = 1;
  1258. X    }
  1259. X    if (v > 0) (*Dataout)(p);
  1260. X    (void)fclose(pfin);
  1261. X    if ( r==0 ) {
  1262. X        libtodisplay(Libindex=0);
  1263. X        clearmess();
  1264. X    }
  1265. X}
  1266. X
  1267. X/* write current library bank to a file */
  1268. Xwriteall()
  1269. X{
  1270. X    char fname[100];
  1271. X    FILE *f;
  1272. X    int v, n;
  1273. X    char *p;
  1274. X
  1275. X    message("File name --> ");
  1276. X    windgets(fname);
  1277. X#ifdef BSD
  1278. X    OPENBINFILE(f,fname,"w");
  1279. X#else
  1280. X    OPENBINFILE(f,fname,"wb");
  1281. X#endif
  1282. X    if ( f == NULL ) {
  1283. X        (void)sprintf(Buff,"Can't open '%s'!",fname);
  1284. X        message(Buff);
  1285. X        return;
  1286. X    }
  1287. X    if (DataID) putc(DataID,f);        /* write data identifier */
  1288. X
  1289. X    p = bankvoice(0);
  1290. X    for ( v=0; v<Nvoices; v++ ) {
  1291. X        for ( n=0; n<Voicesize; n++ )
  1292. X            putc(*p++,f);
  1293. X    }
  1294. X    (void)fclose(f);
  1295. X    clearmess();
  1296. X}
  1297. X
  1298. X
  1299. XFILE *pfout;
  1300. Xint pfoutflag = 0;
  1301. X
  1302. X/* write current library bank to a file in printable form */
  1303. Xwriteprintable()
  1304. X{
  1305. X    char fname[100];
  1306. X    int v;
  1307. X    char *p, *q;
  1308. X
  1309. X    message("File name --> ");
  1310. X    windgets(fname);
  1311. X#ifdef BSD
  1312. X    OPENBINFILE(pfout,fname,"w");
  1313. X#else
  1314. X    OPENBINFILE(pfout,fname,"wb");
  1315. X#endif
  1316. X    if ( pfout == NULL ) {
  1317. X        (void)sprintf(Buff,"Can't open '%s'!",fname);
  1318. X        message(Buff);
  1319. X        return;
  1320. X    }
  1321. X    fprintf(pfout, "BANK TYPE %d\n", DataID);
  1322. X
  1323. X    for (v=0; v<Nvoices; v++) {
  1324. X        p = bankvoice(v);
  1325. X        q = (*Nameof)(p);
  1326. X        if (q[0] > ' ') {
  1327. X            (*Datain)(p);
  1328. X            fprintf(pfout, "voice %d = %s\n", v+1, q);
  1329. X            pfoutflag = 1;
  1330. X            (*Dataout)(p);
  1331. X            pfoutflag = 0;
  1332. X        }
  1333. X    }
  1334. X    (void)fclose(pfout);
  1335. X    clearmess();
  1336. X}
  1337. X
  1338. X/* draw main library/synth voice bank screen */
  1339. Xdrawall()
  1340. X{
  1341. X    windclear();
  1342. X    template();
  1343. X    libtodisplay(Libindex);
  1344. X    syntodisplay(Synindex);
  1345. X    editto(Editrow,Editcol);
  1346. X    pryankname();
  1347. X    showchan();
  1348. X}
  1349. X
  1350. X/*
  1351. X * tosyn
  1352. X *
  1353. X * Store the given 'data' in in voice 'voicenum' (both in Syndata
  1354. X * AND on the synth itself).  If swap is non-zero, the voice is swapped
  1355. X * with the current voice in Syndata.
  1356. X */
  1357. X
  1358. Xtosyn(voicenum,data,swap)
  1359. Xchar *data;
  1360. X{
  1361. X    int n, t;
  1362. X
  1363. X    for ( n=0; n<Voicesize; n++ ) {
  1364. X        if ( swap ) {
  1365. X            t = VOICEBYTE(Syndata,voicenum,n);
  1366. X            VOICEBYTE(Syndata,voicenum,n) = data[n];
  1367. X            data[n] = t;
  1368. X        }
  1369. X        else
  1370. X            VOICEBYTE(Syndata,voicenum,n) = data[n];
  1371. X    }
  1372. X}
  1373. X
  1374. Xtolib(voicenum,data,swap)
  1375. Xchar *data;
  1376. X{
  1377. X    int n, t;
  1378. X    char *p = bankvoice(voicenum);
  1379. X
  1380. X    for ( n=0; n<Voicesize; n++ ) {
  1381. X        if ( swap ) {
  1382. X            t = *p;
  1383. X            *p = data[n];
  1384. X            data[n] = t;
  1385. X        }
  1386. X        else
  1387. X            *p = data[n];
  1388. X        p++;
  1389. X    }
  1390. X}
  1391. X
  1392. Xtocurrent(data,voicenum)
  1393. Xchar *data;
  1394. Xint voicenum;
  1395. X{
  1396. X    int n, f = 0;
  1397. X
  1398. X    for ( n=0; n<Voicesize; n++ )
  1399. X        if ( (Currdata[n] = VOICEBYTE(data,voicenum,n)) != 0) f = 1;
  1400. X    if( f == 1 && !synthoutfileflag) (*Sendedit)(Currdata);
  1401. X}
  1402. X
  1403. X/*
  1404. X * readsynth
  1405. X *
  1406. X * Read a bulk dump from the synth, with some tolerance for errors.
  1407. X */
  1408. Xreadsynth(data)
  1409. Xchar *data;
  1410. X{
  1411. X    if ( Getbulk == NULL ) {
  1412. X        message("That synth is unable to dump anything!!");
  1413. X        return(1);
  1414. X    }
  1415. X    if (synthinfileflag) {
  1416. X        message("Input synth file --> ");
  1417. X        windgets(Syinfname);
  1418. X        synthoutfileflag = 1;
  1419. X        flushmidi();
  1420. X        synthoutfileflag = 0;
  1421. X    }
  1422. X    else message("Downloading from synth");
  1423. X
  1424. X    if ( (*Getbulk)(data) == 0 )
  1425. X        return(0);
  1426. X
  1427. X    message("Unable to read data from synth!");
  1428. X    (void)sprintf(Buff,"Reason: %s",Reason);
  1429. X    message(Buff);
  1430. X    message("Perhaps connections are amiss?");
  1431. X    return(1);
  1432. X}
  1433. X
  1434. Xchar *
  1435. Xvnumtext(n)
  1436. X{
  1437. X    static char vnbuff[6];
  1438. X
  1439. X    if ( Numof == NULL ) {
  1440. X        (void)sprintf(vnbuff,"%2d",n);
  1441. X        return(vnbuff);
  1442. X    }
  1443. X    else
  1444. X        return((*Numof)(n - 1)); /* keep this 0-based */
  1445. X}
  1446. X
  1447. X/*
  1448. X * syntodisplay(n)
  1449. X *
  1450. X * Tranfer Syndata names to dialog boxes (Dxvoices) starting at n.
  1451. X */
  1452. Xsyntodisplay(n)
  1453. X{
  1454. X    int k, r, q;
  1455. X
  1456. X    if(Nvoices < NUMONSCREEN)
  1457. X        q = Nvoices;
  1458. X    else
  1459. X        q = NUMONSCREEN;
  1460. X    for ( k=0; k<q; k++ ) {
  1461. X        r = FIRSTROW+1+k;
  1462. X        windgoto(r,LEFTSIDE);
  1463. X        (void)sprintf(Buff,"%s |                 ",vnumtext(n+k+1));
  1464. X        windstr(Buff);
  1465. X        /* pull the name out of the Syndata */
  1466. X        if ( Namesize != 0 ) {
  1467. X            windgoto(r,LEFTSIDE+5);
  1468. X            windstr((*Nameof)( & (VOICEBYTE(Syndata,n+k,0) )) );
  1469. X        }
  1470. X    }
  1471. X    windrefresh();
  1472. X#ifdef KAWAIK1
  1473. X    synnames();
  1474. X#endif
  1475. X}
  1476. X
  1477. X#ifdef KAWAIK1
  1478. X/*
  1479. X * synnames()
  1480. X *
  1481. X * Tranfer Syndata names to array.
  1482. X */
  1483. Xsynnames()
  1484. X{    int i, k;
  1485. X    char *p, *q;
  1486. X
  1487. X    if (Nvoices != 64) return;
  1488. X
  1489. X    for ( k=0; k < 64; k++ ) {
  1490. X        p = (*Nameof)( & (VOICEBYTE(Syndata,k,0) ));
  1491. X        q = sngnames[k];
  1492. X        for (i=0; i < 10; i++) *q++ = *p++;
  1493. X        *q = 0;
  1494. X    }
  1495. X}
  1496. X#endif
  1497. X
  1498. X/*
  1499. X * libtodisplay
  1500. X *
  1501. X * Tranfer Libdata names to the screen, starting at voice 'firstv'.
  1502. X */
  1503. X
  1504. Xlibtodisplay(firstv)
  1505. X{
  1506. X    int k, r, q;
  1507. X
  1508. X    windgoto(FIRSTROW-1,RIGHTSIDE+2);
  1509. X    (void)sprintf(Buff,"Library (Bank %d)",Libbank+1);
  1510. X    windstr(Buff);
  1511. X
  1512. X    if(Nvoices < NUMONSCREEN)
  1513. X        q = Nvoices;
  1514. X    else
  1515. X        q = NUMONSCREEN;
  1516. X    for ( k=0; k<q; k++ ) {
  1517. X        r = FIRSTROW+1+k;
  1518. X        windgoto(r,RIGHTSIDE);
  1519. X        (void)sprintf(Buff,"%s |                 ",vnumtext(firstv+k+1));
  1520. X        windstr(Buff);
  1521. X        /* pull the name out of the Libdata */
  1522. X        if ( Namesize != 0 ) {
  1523. X            windgoto(r,RIGHTSIDE+5);
  1524. X            windstr((*Nameof)(bankvoice(firstv+k)));
  1525. X        }
  1526. X    }
  1527. X    windrefresh();
  1528. X}
  1529. X
  1530. Xallnotesoff()
  1531. X{
  1532. X    int n;
  1533. X
  1534. X    /* Go through all channels. */
  1535. X    for ( n=0; n<15; n++ ) {
  1536. X        sendmidi(n | 0xb0);
  1537. X        sendmidi(0x7b);
  1538. X        sendmidi(0x00);
  1539. X    }
  1540. X}
  1541. X
  1542. X/*
  1543. X * Below are generic edit routines, which manage a screen display
  1544. X * showing parameter values, and let you roam around and make changes.
  1545. X * The display is managed by the contents of the P array, which
  1546. X * contains the name, screen location, min/max values, etc. of
  1547. X * each parameter.
  1548. X */
  1549. X
  1550. Xint Prow = 0;
  1551. Xint Pcol = 0;
  1552. Xint Parm = 0;
  1553. X
  1554. X/* redraw the parameter screen */
  1555. Xshowallparms(name)
  1556. Xchar *name;
  1557. X{
  1558. X    int n;
  1559. X    char *s;
  1560. X
  1561. X    windclear();
  1562. X
  1563. X    if( Namesize != 0 ) {
  1564. X        showname(name);
  1565. X        windgoto(1,0);
  1566. X        for(n=strlen(name)+6;n>0;n--)
  1567. X            windputc('=');
  1568. X    }
  1569. X
  1570. X    /* The L array contains arbitrary screen labels */
  1571. X    for ( n=0; L[n].l_text != NULL; n++ ) {
  1572. X        windgoto(L[n].l_row,L[n].l_col);
  1573. X        windstr(L[n].l_text);
  1574. X    }
  1575. X    /* Display each parameter value, and a label if there is one. */
  1576. X    for ( n=0; P[n].p_name != NULL; n++ ) {
  1577. X        if ( P[n].p_flags != 0 )
  1578. X            continue;
  1579. X        if ( (s=P[n].p_label) != NULL )
  1580. X            showstr(s,P[n].p_lrow,P[n].p_lcol,0);
  1581. X        showparam(n,0);
  1582. X    }
  1583. X    windrefresh();
  1584. X}
  1585. X
  1586. Xshowname(name)
  1587. Xchar *name;
  1588. X{
  1589. X    windgoto(0,0);
  1590. X    windstr("Name:                 ");
  1591. X    windgoto(0,6);
  1592. X    windstr(name);
  1593. X}
  1594. X
  1595. Xshowparam(n,eras)
  1596. X{
  1597. X    char *p;
  1598. X
  1599. X    /* The p_tovis element of the P array is a function which, given */
  1600. X    /* the parameter value as an argument, returns a string which is */
  1601. X    /* what should be displayed on the screen. */
  1602. X#ifdef DX7
  1603. X        if (P[n].p_vrow < 0 || P[n].p_vcol < 0) return;
  1604. X    p = (*(P[n].p_tovis))(P[n].p_val, eras);
  1605. X#else
  1606. X    p = (*(P[n].p_tovis))(P[n].p_val);
  1607. X#endif
  1608. X    showstr(p,P[n].p_vrow,P[n].p_vcol,eras);
  1609. X}
  1610. X
  1611. X#ifdef DX7
  1612. X
  1613. X/*
  1614. X * define defaults for the graphics characters, if they haven't been specified
  1615. X * in machdep.
  1616. X */
  1617. X
  1618. X# ifndef DRAW_VERT
  1619. X#  define DRAW_VERT      '|'
  1620. X#  define DRAW_HORIZ     '-'
  1621. X#  define DRAW_CROSS     '+'
  1622. X#  define DRAW_UPTEE     '+'
  1623. X#  define DRAW_DOWNTEE   '+'
  1624. X#  define DRAW_LEFTTEE   '+'
  1625. X#  define DRAW_RIGHTTEE  '+'
  1626. X#  define DRAW_UPLEFT    '+'
  1627. X#  define DRAW_UPRIGHT   '+'
  1628. X#  define DRAW_DOWNLEFT  '+'
  1629. X#  define DRAW_DOWNRIGHT '+'
  1630. X# endif
  1631. X
  1632. Xshowstr(p,row,col,eras)
  1633. Xregister char *p;
  1634. Xregister int col;
  1635. X{
  1636. X  register int c;
  1637. X  int rept, mincol;
  1638. X
  1639. X  mincol = col;
  1640. X
  1641. X  windgoto(row,col);
  1642. X  while ( (c=(*p++)) != '\0' ) {
  1643. X    switch(c){
  1644. X      case '~':
  1645. X        c = *p++;
  1646. X        if (isdigit(c)) {
  1647. X          rept = 0;
  1648. X          while (isdigit(c)) {
  1649. X            rept = 10*rept + (c-'0');
  1650. X            c = *p++;
  1651. X          }
  1652. X        }
  1653. X        else
  1654. X          rept = 1;
  1655. X
  1656. X        while (rept--) {
  1657. X          switch( c ) {
  1658. X            case 'n': row++; col=mincol; goto wgoto;
  1659. X            case 'u': row--; goto wgoto;
  1660. X            case 'd': row++; goto wgoto;
  1661. X            case 'l': col--; if (col < mincol) mincol = col; goto wgoto;
  1662. X            case 'r': col++;
  1663. X              wgoto:
  1664. X                windgoto(row,col);
  1665. X                break;
  1666. X            case '|': c=DRAW_VERT;      goto wput;
  1667. X            case '-': c=DRAW_HORIZ;     goto wput;
  1668. X            case '+': c=DRAW_CROSS;     goto wput;
  1669. X            case 'T': c=DRAW_UPTEE;     goto wput;
  1670. X            case '^': c=DRAW_DOWNTEE;   goto wput;
  1671. X            case '<': c=DRAW_RIGHTTEE;  goto wput;
  1672. X            case '>': c=DRAW_LEFTTEE;   goto wput;
  1673. X            case '{': c=DRAW_UPLEFT;    goto wput;
  1674. X            case '}': c=DRAW_UPRIGHT;   goto wput;
  1675. X            case '[': c=DRAW_DOWNLEFT;  goto wput;
  1676. X            case ']': c=DRAW_DOWNRIGHT;
  1677. X              wput:
  1678. X                windputc(eras?' ':c);
  1679. X                col++;
  1680. X                break;
  1681. X            default:
  1682. X              windputc(eras?' ':c);
  1683. X              col++;
  1684. X              break;
  1685. X          }
  1686. X        }
  1687. X        break;
  1688. X      default:
  1689. X        windputc(eras?' ':c);
  1690. X        col++;
  1691. X        break;
  1692. X    }
  1693. X  }
  1694. X}
  1695. X
  1696. X#else  /* DX7 */
  1697. X
  1698. Xshowstr(p,row,col,eras)
  1699. Xregister char *p;
  1700. Xregister int col;
  1701. X{
  1702. X    register int c;
  1703. X
  1704. X    windgoto(row,col);
  1705. X    while ( (c=(*p++)) != '\0' ) {
  1706. X        switch(c){
  1707. X        case '~':
  1708. X            switch( (c=(*p++)) ) {
  1709. X            case 'u': row--; goto wgoto;
  1710. X            case 'd': row++; goto wgoto;
  1711. X            case 'l': col--; goto wgoto;
  1712. X            case 'r': col++;
  1713. X                wgoto:
  1714. X                windgoto(row,col);
  1715. X                break;
  1716. X            default:
  1717. X                windputc(eras?' ':c);
  1718. X                col++;
  1719. X                break;
  1720. X            }
  1721. X            break;
  1722. X        default:
  1723. X            windputc(eras?' ':c);
  1724. X            col++;
  1725. X            break;
  1726. X        }
  1727. X    }
  1728. X}
  1729. X#endif
  1730. X
  1731. X/* Allow roaming around and changing of parameter values. */
  1732. Xeditdata(name,data)
  1733. Xchar *name;
  1734. Xchar *data;    /* vmem format */
  1735. X{
  1736. X    int c, n;
  1737. X
  1738. X    windclear();
  1739. X    windrefresh();
  1740. X    /* enable all the parameters */
  1741. X    for ( n=0; P[n].p_name != NULL; n++ )
  1742. X        enableparm(n);
  1743. X
  1744. X    /* Take the voice data and put it into P */
  1745. X    (*Datain)(data);
  1746. X
  1747. X    Prow = Pcol = 0;
  1748. X    Changed = 0;
  1749. X    Redraw = 1;
  1750. X    Lastvalue = 0;
  1751. X    gotoparm(CH_RIGHT);    /* Get to the first parameter */
  1752. X    for ( ;; ) {
  1753. X        if ( Redraw ) {
  1754. X            showallparms(name);
  1755. X            Redraw = 0;
  1756. X        }
  1757. X        windgoto(Prow,Pcol);
  1758. X        windrefresh();
  1759. X        c = mouseorkey();
  1760. X        if ( c == MOUSE ) {
  1761. X            editmouse();
  1762. X            continue;
  1763. X        }
  1764. X        switch(c){
  1765. X        case CH_RIGHT:
  1766. X        case ALTCH_RIGHT:
  1767. X        case CH_UP:
  1768. X        case ALTCH_UP:
  1769. X        case CH_DOWN:
  1770. X        case ALTCH_DOWN:
  1771. X        case CH_LEFT:
  1772. X        case ALTCH_LEFT:
  1773. X            gotoparm(c);
  1774. X            break;
  1775. X        case CH_SAME:
  1776. X            sameparm();
  1777. X            break;
  1778. X        case CH_REDRAW:
  1779. X            showallparms(name);
  1780. X            break;
  1781. X        case 'N':
  1782. X            if ( Namesize != 0 ) {
  1783. X            /* Allow changing of voice name */
  1784. X                windgoto(0,5);
  1785. X                windstr("                ");
  1786. X                windgoto(0,6);
  1787. X                windrefresh();
  1788. X                windgets(Buff);
  1789. X                if ( Buff[0]!='\0' && Buff[0]!='\n' )
  1790. X                    (*Setnameof)(data,Buff);
  1791. X                showname(name=(*Nameof)(data));
  1792. X                Changed = 1;
  1793. X            }
  1794. X            break;
  1795. X
  1796. X        case CH_INC:
  1797. X            adjuparm(1);
  1798. X            break;
  1799. X        case CH_INC2:
  1800. X            adjuparm(4);
  1801. X            break;
  1802. X        case CH_INC3:
  1803. X            adjuparm(P[Parm].p_max - P[Parm].p_min);
  1804. X            break;
  1805. X        case CH_DEC:
  1806. X            adjuparm(-1);
  1807. X            break;
  1808. X        case CH_DEC2:
  1809. X            adjuparm(-4);
  1810. X            break;
  1811. X        case CH_DEC3:
  1812. X            adjuparm(P[Parm].p_min - P[Parm].p_max);
  1813. X            break;
  1814. X#ifdef OLDSTUFF
  1815. X        case 'a':
  1816. X            sendaced(data);
  1817. X            playnote(0);
  1818. X            break;
  1819. X#endif
  1820. X        case ' ':
  1821. X        case '\n':
  1822. X#ifndef macintosh
  1823. X        case '\r':
  1824. X#endif
  1825. X            if ( Changed ) {
  1826. X                (*Dataout)(data);
  1827. X                (*Sendedit)(data);
  1828. X                Changed = 0;
  1829. X            }
  1830. X            playnote(0);
  1831. X            break;
  1832. X        case '\033':
  1833. X        case '`':
  1834. X            allnotesoff();
  1835. X            break;
  1836. X        case 'q':
  1837. X        case EOF:
  1838. X            if ( Changed ) {
  1839. X                (*Dataout)(data);
  1840. X                (*Sendedit)(data);
  1841. X            }
  1842. X            return;
  1843. X        default:
  1844. X            break;
  1845. X        }
  1846. X    }
  1847. X}
  1848. X
  1849. Xadjuparm(incdec)
  1850. X{
  1851. X    int v, n;
  1852. X
  1853. X    v = P[Parm].p_val + incdec;
  1854. X    if ( v < (n=P[Parm].p_min) )
  1855. X        v = n;
  1856. X    if ( v > (n=P[Parm].p_max) )
  1857. X        v = n;
  1858. X    Lastvalue = v;
  1859. X    Changed = 1;
  1860. X    showparam(Parm,1);    /* erase the old val */
  1861. X    P[Parm].p_val = v;
  1862. X    showparam(Parm,0);    /* show the new val */
  1863. X}
  1864. X
  1865. Xsameparm()
  1866. X{
  1867. X    int v, n;
  1868. X
  1869. X    v = Lastvalue;
  1870. X    if ( v < (n=P[Parm].p_min) )
  1871. X        v = n;
  1872. X    if ( v > (n=P[Parm].p_max) )
  1873. X        v = n;
  1874. X    Changed = 1;
  1875. X    showparam(Parm,1);    /* erase the old val */
  1876. X    P[Parm].p_val = v;
  1877. X    showparam(Parm,0);    /* show the new val */
  1878. X}
  1879. X
  1880. Xeditmouse()
  1881. X{
  1882. X    int row, col, thisparm;
  1883. X
  1884. X    getmouse(&row,&col);
  1885. X    thisparm = closeparm(row,col);
  1886. X    if ( thisparm == Parm ) {
  1887. X        if ( statmouse() > 1 )
  1888. X            adjuparm(-1);    /* right button */
  1889. X        else if ( statmouse() == 1 ) /* added by mab - bug fix */
  1890. X            adjuparm(1);    /* left button */
  1891. X    }
  1892. X    else {
  1893. X        Parm = thisparm;
  1894. X        Prow = P[Parm].p_vrow;
  1895. X        Pcol = P[Parm].p_vcol;
  1896. X    }
  1897. X}
  1898. X
  1899. X/* closeparm - Find the closest parameter */
  1900. Xcloseparm(row,col)
  1901. X{
  1902. X    register struct paraminfo *pp;
  1903. X    register int n;
  1904. X    int dist, mindist, minparm, dr, dc;
  1905. X
  1906. X    minparm = 0;
  1907. X    mindist = Rows + Cols;
  1908. X    for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) {
  1909. X        if ( pp->p_flags != 0 )
  1910. X            continue;
  1911. X        if ( (dr=row-(pp->p_vrow)) < 0 )
  1912. X            dr = -dr;
  1913. X        if ( (dc=col-(pp->p_vcol)) < 0 )
  1914. X            dc = -dc;
  1915. X        if ( (dist=dr*dr+dc*dc) < mindist ) {
  1916. X            minparm = n;
  1917. X            mindist = dist;
  1918. X        }
  1919. X    }
  1920. X    return(minparm);
  1921. X}
  1922. X
  1923. X/* playnote - play the 'auto' note */
  1924. Xplaynote(i)
  1925. X{
  1926. X    int pitch, vol, dur, chan;
  1927. X    long endtime;
  1928. X
  1929. X    pitch = getval("autopitch");
  1930. X    if(i == 0) { /* called from inside edit-mode */
  1931. X        chan = getval("autochan");
  1932. X    } else { /* called from the top level */
  1933. X        chan = Channel;
  1934. X    }
  1935. X    vol = getval("autovol");
  1936. X    dur = getval("autodur");
  1937. X    endtime = milliclock() + dur * 100;
  1938. X    midinote(1,chan,pitch,vol);
  1939. X    while ( milliclock() < endtime )
  1940. X        ;
  1941. X    midinote(0,chan,pitch,vol);
  1942. X}
  1943. X
  1944. X/* gotoparm - search for the next parameter in the specified direction */
  1945. Xgotoparm(dir)
  1946. X{
  1947. X    int n, k, inc, pm, orig, r = Prow, c = Pcol;
  1948. X
  1949. X    switch(dir) {
  1950. X    case ALTCH_UP:        dir = CH_UP;    break;
  1951. X    case ALTCH_DOWN:    dir = CH_DOWN;    break;
  1952. X    case ALTCH_LEFT:    dir = CH_LEFT;    break;
  1953. X    case ALTCH_RIGHT:    dir = CH_RIGHT;    break;
  1954. X    }
  1955. X
  1956. X    if ( dir==CH_LEFT || dir==CH_RIGHT ) {
  1957. X        if ( dir==CH_LEFT )
  1958. X            c--;
  1959. X        else
  1960. X            c++;
  1961. X        orig = c;
  1962. X        inc = 0;
  1963. X        pm = -1;
  1964. X        /* look up and down, alternately */
  1965. X        for ( n=2*Rows; n>0; n-- ) {
  1966. X            r += (pm * inc++);
  1967. X            pm = -pm;
  1968. X            if ( r < 0 || r >= Rows )
  1969. X                continue;
  1970. X            if ( dir == CH_LEFT ) {
  1971. X                for ( c=orig; c>=0; c-- ) {
  1972. X                    if ( parmat(r,c) )
  1973. X                        return;
  1974. X                }
  1975. X            }
  1976. X            else {
  1977. X                for ( c=orig; c<Cols; c++ ) {
  1978. X                    if ( parmat(r,c) )
  1979. X                        return;
  1980. X                }
  1981. X            }
  1982. X        }
  1983. X        return;
  1984. X    }
  1985. X    if ( dir==CH_DOWN || dir==CH_UP ) {
  1986. X        if ( dir==CH_DOWN )
  1987. X            r++;
  1988. X        else
  1989. X            r--;
  1990. X        orig = c;
  1991. X        while ( r >= 0 && r < Rows ) {
  1992. X            /* look toward both sides at the same time */
  1993. X            inc = 0;
  1994. X            pm = -1;
  1995. X            for ( k=2*Cols; k>0; k-- ) {
  1996. X                c += (pm * inc++);
  1997. X                pm = -pm;
  1998. X                if ( c < 0 || c >= Cols )
  1999. X                    continue;
  2000. X                if ( parmat(r,c) )
  2001. X                    return;
  2002. X            }
  2003. X            if ( dir==CH_DOWN )
  2004. X                r++;
  2005. X            else
  2006. X                r--;
  2007. X            c = orig;
  2008. X        }
  2009. X        return;
  2010. X    }
  2011. X}
  2012. X
  2013. X/* paramat - return non-zero if a parameter value is at position r,c */
  2014. Xparmat(r,c)
  2015. Xregister int r, c;
  2016. X{
  2017. X#ifdef SSS
  2018. X  int p = PARAMAT(r, c);
  2019. X
  2020. X  if (p == 0 || P[p-1].p_flags)
  2021. X    return 0;
  2022. X  else {
  2023. X    Parm = p-1;
  2024. X    Prow = r;
  2025. X    Pcol = c;
  2026. X    return 1;
  2027. X  }
  2028. X#else
  2029. X    register int n;
  2030. X    register struct paraminfo *pp;
  2031. X
  2032. X    for ( n=0,pp=P; pp->p_name != NULL; n++,pp++ ) {
  2033. X        if ( pp->p_flags != 0 )
  2034. X            continue;
  2035. X        if ( pp->p_vrow==r && pp->p_vcol==c ) {
  2036. X            Prow = r;
  2037. X            Pcol = c;
  2038. X            Parm = n;
  2039. X            return(1);
  2040. X        }
  2041. X    }
  2042. X    return(0);
  2043. X#endif
  2044. X}
  2045. X
  2046. X/* parmindex - return index (in P) of a given parameter name. */
  2047. Xparmindex(name)
  2048. Xchar *name;
  2049. X{
  2050. X#ifdef SSS
  2051. X  struct paraminfo key, *p;
  2052. X  extern char *bsearch();
  2053. X
  2054. X  key.p_name = name;
  2055. X  p = (struct paraminfo *)bsearch((void *)&key, (void *)P, NParams,
  2056. X        sizeof(struct paraminfo), paramcmp);
  2057. X  if (p == 0) {
  2058. X    (void)sprintf(Buff,"HEY, PARMINDEX(%s) NOT FOUND!\n",name);
  2059. X    windstr(Buff);
  2060. X    windrefresh();
  2061. X    return(-1);
  2062. X  }
  2063. X  else
  2064. X    return p-P;
  2065. X#else
  2066. X    int n;
  2067. X    char *s;
  2068. X
  2069. X    for ( n=0; (s=P[n].p_name) != NULL; n++ ) {
  2070. X        if ( strcmp(s,name) == 0 )
  2071. X            return(n);
  2072. X    }
  2073. X    (void)sprintf(Buff,"HEY, PARMINDEX(%s) NOT FOUND!\n",name);
  2074. X    windstr(Buff);
  2075. X    windrefresh();
  2076. X    return(-1);
  2077. X#endif
  2078. X}
  2079. X
  2080. Xvoid
  2081. Xsetval(name,v)
  2082. XINT16 v;
  2083. Xchar *name;
  2084. X{
  2085. X    int n;
  2086. X
  2087. X    if ( (n=parmindex(name)) < 0 )
  2088. X        return;
  2089. X    P[n].p_val = v;
  2090. X}
  2091. X
  2092. Xint
  2093. Xgetval(name)
  2094. Xchar *name;
  2095. X{
  2096. X    int n;
  2097. X
  2098. X    if ( (n=parmindex(name)) < 0 )
  2099. X        return(0);
  2100. X
  2101. X    if (pfoutflag)
  2102. X        fprintf(pfout, "%s = %d\n", name, P[n].p_val);
  2103. X
  2104. X    return(P[n].p_val);
  2105. X}
  2106. X
  2107. X
  2108. Xenableparm(n)
  2109. X{
  2110. X    if ( P[n].p_flags != 0 )
  2111. X        P[n].p_flags = 0;
  2112. X}
  2113. X
  2114. Xdisableparm(n)
  2115. X{
  2116. X    if ( P[n].p_flags == 0 )
  2117. X        P[n].p_flags = 1;
  2118. X}
  2119. X
  2120. Xmidinote(onoff,chan,pitch,vol)
  2121. X{
  2122. X    sendmidi( ((onoff==1)?(0x90):(0x80)) | ((chan-1)&0xf) );
  2123. X    sendmidi( pitch & 0x7f );
  2124. X    sendmidi( vol & 0x7f );
  2125. X}
  2126. X
  2127. Xstatic char Nbuff[16];
  2128. X
  2129. Xchar *visnum(v)
  2130. X{
  2131. X    (void)sprintf(Nbuff,"%d",v);
  2132. X    return(Nbuff);
  2133. X}
  2134. Xchar *visonoff(v)
  2135. X{
  2136. X    if ( v==0 )
  2137. X        return("OFF");
  2138. X    else
  2139. X        return("ON ");
  2140. X}
  2141. X
  2142. Xchar *
  2143. Xbankvoice(voice)
  2144. X{
  2145. X    int offset = Libbank * Nvoices * Voicesize + voice * Voicesize;
  2146. X    return(Libdata + offset);
  2147. X}
  2148. END_OF_FILE
  2149. if test 41661 -ne `wc -c <'glib.c'`; then
  2150.     echo shar: \"'glib.c'\" unpacked with wrong size!
  2151. fi
  2152. # end of 'glib.c'
  2153. fi
  2154. echo shar: End of archive 15 \(of 15\).
  2155. cp /dev/null ark15isdone
  2156. MISSING=""
  2157. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  2158.     if test ! -f ark${I}isdone ; then
  2159.     MISSING="${MISSING} ${I}"
  2160.     fi
  2161. done
  2162. if test "${MISSING}" = "" ; then
  2163.     echo You have unpacked all 15 archives.
  2164.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2165. else
  2166.     echo You still need to unpack the following archives:
  2167.     echo "        " ${MISSING}
  2168. fi
  2169. ##  End of shell archive.
  2170. exit 0
  2171.  
  2172.